B树C语言实现-创建、插入、删除

1. 课程设计题目标题:  B树的基本操作算法(创建、插入、删除)

问题描述:

 在计算机科学中,B树在查找、访问、插入、删除操作上时间复杂度为O(log2~n),与自平衡二叉查找树不同的是B树对大块数据读写的操作有更优的性能,其通常在数据库和文件系统中被使用。  

对于一棵B树,对其进行创建、插入、删除的基本操作。

2. 算法描述

(1) 总体思路(最初的算法)

一棵m阶的B树,或为空树,或为满足下列特征的m叉树:

 ①、树中每个结点至多有m棵子树;    

 ②、若根结点不是终端结点,则至少有2棵子树;

 ③、除根之外,所有非终端结点至少有棵子树;    

 ④、所有的非终端结点中包含下列信息数据: [n, C0, K0, C1, K1, C2, K2, ...., Kn-1, Cn]         其中:Ki[i=0,1,...,n-1]为关键字,且Ki<Ki+1[i=0, 1, ..., n-2];Ci[i=0,1,...,n]为至上子树根结点的指针,且指针Ci所指子树中所有结点的关键字均小于Ki[i=0,1,...,n-1],但都大于Ki-1[i=1,...,n-1];

数据结构:

(2) 第二版本算法

基本操作之插入的步骤:

B树是从空树起,逐个插入关键字而建立起来的,由于B树结点中的关键字个数num必须>=,因此,每次插入一个关键字不是在树中添加一个终端结点,而是首先在最底层的某个非终端结点中插入一个关键字,若该结点的关键字个数不超过m-1,则插入完成,否则要进行结点的“分裂”。

  假设结点node的关键字个数num>max,则需进行分裂处理,其大体处理流程如下:

  1) 结点node以sidx关键字为分割点,索引(0 ~ sidx-1)关键字继续留在结点node中,索引(sidx+1 ~ num-1)关键字放入新结点node2中

  2) 而索引sidx关键字则插入node->parent中,再将新结点node2作为父结点新插入关键字的右孩子结点

  3) 判断插入node的sidx关键字后,node->parent的关键字个数num是否超过max,如果超过,则以parent为操作对象进行1)的处理;否则,处理结束。

 

 

当结点关键字个数num达到max时,则需要进行“分裂”处理,分割序号为num/2。分裂过程如下:

    ->1) 以序列号idx=num/2为分割点,原结点分裂为2个结点A和B;

    ->2) 原结点无父结点,则新建一个结点P,并将关键字插入到新结点P中;若有父节点就直接把AB作为父节点的子结点

    ->3) 将结点A和B作为结点P的子结点,并遵循B树特征④;

    ->4) 因结点P的结点数未超过max,则分裂结束。

 

(3) 第三版本算法

基本操作之删除的步骤:

假设现有一棵m阶的B树,则单个结点的关键字最大个数max=m-1,关键字最小个数min=。假设被删关键字key为结点node中的第idx个关键字,由B树的特征可知,在删除操作之前,结点node的关键字个数num需满足min <= num <= max)。  

情况1:被删关键字KEY所在结点node为非最底层结点时    

Step1:找到被删关键字KEY在结点node中的位置idx —— 即:node->key[idx]为将被删除的关键字    

Step2:找到以子结点child = node->child[idx]为根节点的子树    

Step3:再找到该子树中的最大关键字KEY2,并将之拿去填充被删关键字KEY的位置,即:node->key[idx] = KEY2。 —— 子树最大关键字MaxKey被拿走后,相当于子树最大关键字的原位置被空缺了出来,也可在一定意义上理解为最终删除的子树中的最大关键字。    

经过思考后可发现:以子结点child = node->child[idx]为根节点的子树中最大关键字一定是在最底层某个结点中,不管要求被删的关键字KEY在哪个结点,均可视为最终被删的关键字都是在最底层结点中,而最底层结点的处理请参考2)的处理流程。

 

  

 情况2:被删关键字KEY所在结点node为最底层结点时    

2.1) 删除操作前,结点node的关键字个数num>时,则进行删除操作后,结点node关键字个数num仍然处在min <= num <= max的范围之中,此时删除操作处理完成;    

2.2) 删除操作前,结点node的关键字个数num=时,则进行删除操作后,结点node的关键字个数num<,显然已经不符合B树的特征,为了维护B树的特征,此时需要进行的处理有2种情况:    

->2.2.1) 如果结点node的兄弟结点brother的结点个数num>时,则结点node可以向brother借用一个结点,但是需要以父结点的关键字为跳板,此时删除操作处理完成;    

->2.2.2) 如果结点node的兄弟结点brother的节点个数num=时,则将node和brother进行合并为一个结点new,同时需要将父结点parent中夹在node和brother之间的关键字插入到新结点new中。如果父结点parent中的一个关键字被插入到了新结点后,父结点parent的关键字个数num>=,则删除操作处理完成; 如果父结点parent的关键字个数num<,则父结点parent此时已经不满足B树特征,则需以父结点为操作对象进行2.2)中的情况判断,并依次类推直至根结点。

3. 数据结构

typedef struct _btree_node_t  
{  
    int num;                      /*关键字个数*/ 
    int *key;                     /* 关键字:所占空间为(max+1) - 多出来的1个空间用于交换空间使用 */  
    struct _btree_node_t **child

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值